﻿using System;
using System.Collections.Generic;

namespace Microsoft.Goldenlight.Collections
{
    /// <summary>
    /// 	Represents a generic collection of multiple keys and a single value pairs.
    /// </summary>
    /// <typeparam name="TKey1"> The type of first keys in the dictionary. </typeparam>
    /// <typeparam name="TKey2"> The type of second keys in the dictionary. </typeparam>
    /// <typeparam name="TValue"> The type of values in the dictionary. </typeparam>
    public interface IIMultiKeysDictionary<TKey1, TKey2, TValue> : IDictionary<TKey1, IDictionary<TKey2, TValue>>
    {
        #region Properties

        /// <summary>
        /// 	Gets or sets the dictionary of second key and value with the specified first key.
        /// </summary>
        /// <param name="key1"> The first key of the element to get or set. </param>
        /// <returns> The dictionary of second key and value with the specified first key. </returns>
        new IDictionary<TKey2, TValue> this[TKey1 key1]
        {
            get;
            set;
        }

        /// <summary>
        /// 	Gets or sets the element with the specified compounded keys.
        /// </summary>
        /// <param name="key1"> The first key of the element to get or set. </param>
        /// <param name="key2"> The second key of the element to get or set. </param>
        /// <returns> The element with the specified compounded keys. </returns>
        TValue this[TKey1 key1, TKey2 key2]
        {
            get;
            set;
        }

        /// <summary>
        /// 	Gets an ICollection containing the compounded keys of the IIMultiKeysDictionary.
        /// </summary>
        /// <returns> An ICollection containing the compounded keys of the object that implements IIMultiKeysDictionary. </returns>
        new ICollection<Tuple<TKey1, TKey2>> Keys
        {
            get;
        }

        /// <summary>
        /// 	Gets an ICollection containing the first keys of the IMultiKeysDictionary.
        /// </summary>
        /// <returns> An ICollection containing the first keys of the object that implements IMultiKeysDictionary. </returns>
        ICollection<TKey1> Keys1
        {
            get;
        }

        /// <summary>
        /// 	Gets an ICollection containing the second keys of the IMultiKeysDictionary.
        /// </summary>
        /// <returns> An ICollection containing the second keys of the object that implements IMultiKeysDictionary. </returns>
        ICollection<TKey2> Keys2
        {
            get;
        }

        /// <summary>
        /// 	Gets an ICollection containing the values in the IIMultiKeysDictionary.
        /// </summary>
        /// <returns> An ICollection containing the values in the object that implements IIMultiKeysDictionary. </returns>
        new ICollection<TValue> Values
        {
            get;
        }

        #endregion

        #region Operations

        /// <summary>
        /// 	Adds an element with the provided key and value to the IIMultiKeysDictionary.
        /// </summary>
        /// <param name="key1"> The object to use as the key of the element to add. </param>
        /// <param name="key2"> The object to use as the key of the element to add. </param>
        /// <param name="value"> The object to use as the value of the element to add. </param>
        void Add(TKey1 key1, TKey2 key2, TValue value);

        /// <summary>
        /// 	Removes the element with the specified compounded keys from the IIMultiKeysDictionary.
        /// </summary>
        /// <param name="key1"> The first key of the element to remove. </param>
        /// <param name="key2"> The second key of the element to remove. </param>
        /// <returns> True if the element is successfully removed; otherwise, false. This method also returns false if compounded keys were not found in the original IIMultiKeysDictionary. </returns>
        bool Remove(TKey1 key1, TKey2 key2);

        /// <summary>
        /// 	Determines whether the IMultiKeysDictionary contains an element with the specified compounded keys.
        /// </summary>
        /// <returns> True if the IMultiKeysDictionary contains an element with the compounded keys; otherwise, false. </returns>
        /// <param name="key1"> The first key to locate in the IMultiKeysDictionary. </param>
        /// <param name="key2"> The second key to locate in the IMultiKeysDictionary. </param>
        bool ContainsKey(TKey1 key1, TKey2 key2);

        /// <summary>
        /// 	Gets the value associated with the specified compounded keys.
        /// </summary>
        /// <param name="key1"> The first key whose value to get. </param>
        /// <param name="key2"> The second key whose value to get. </param>
        /// <param name="value"> When this method returns, the value associated with the specified compounded keys, if the compounded keys are found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized. </param>
        /// <returns> True if the object that implements IMultiKeysDictionary contains an element with the specified compounded keys; otherwise, false. </returns>
        bool TryGetValue(TKey1 key1, TKey2 key2, out TValue value);

        #endregion
    }
}